Interactive Plots and Diagrams


In [ ]:
using Interact

Interactive plotting can be useful and fun. Here we have a few examples to get you started creating your own interactive plots. We will extensively use the @manipulate macro.

Drawing with svg

The dom".." macro allows us to create any element in the DOM, such as for example svg. Here is an example you can play around with.


In [ ]:
width, height = 700, 300
colors = ["black", "gray", "silver", "maroon", "red", "olive", "yellow", "green", "lime", "teal", "aqua", "navy", "blue", "purple", "fuchsia"]
color(i) = colors[i%length(colors)+1]
ui = @manipulate for nsamples in 1:200,
        sample_step in slider(0.01:0.01:1.0, value=0.1, label="sample step"),
        phase in slider(0:0.1:2pi, value=0.0, label="phase"),
        radii in 0.1:0.1:60
    cxs_unscaled = [i*sample_step + phase for i in 1:nsamples]
    cys = sin.(cxs_unscaled) .* height/3 .+ height/2
    cxs = cxs_unscaled .* width/4pi
    dom"svg:svg[width=$width, height=$height]"(
        (dom"svg:circle[cx=$(cxs[i]), cy=$(cys[i]), r=$radii, fill=$(color(i))]"()
            for i in 1:nsamples)...
    )
end

Plots


In [ ]:
using Plots, Colors

In [ ]:
@manipulate for ϕ = 0:π/16:4π, f = [sin, cos], both = false
    if both
        plot([θ -> sin(θ + ϕ), θ -> cos(θ + ϕ)], 0, 8)
    else
        plot(θ -> f(θ + ϕ), 0, 8)
    end
end

In [ ]:
@manipulate for n=1:25, g=[:scatter, :path], col=colorant"red"
    plot(rand(n), rand(n), linetype=g, color=col)
end

PyPlot


In [ ]:
using PyPlot

Since PyPlot images are often displayed as the result of function side-effects, you'll need to take an extra step in order for interactive PyPlot graphics to be updated properly as widget values are updated. You do this by using the withfig function to specify a figure object that will be updated in each iteration of @manipulate. Notice f = figure() and withfig(f) in the example below. The rest of it is straightforward.


In [ ]:
f = figure()
x = range(0, stop=2π, length=1000)
@manipulate for α=1:0.1:3, β=1:0.1:3, γ=1:0.1:3, leg="a funny plot"; withfig(f) do
        PyPlot.plot(x, cos.(α.*x .+ sin.(β.*x .+ γ)))
        legend([leg])
    end
end

As an added bonus, you can even fire up a Python GUI with pygui(true) and be able to use the widgets above to update the plot.

PyPlot Subplots

Manipulating a PyPlot figure with multiple subplots adds an extra layer of complication. The withfig function clears the current figure window by default at each @manipulate iteration. If you're manipulating multiple subplots in one figure they will not be displayed correctly. To prevent subplots being destroyed use withfig(f,clear=false). Setting clear=false leaves the responsibility for clearing the figure window up to the user. In the case of multiple subplots you can clear each axes object individually, rather than the figure itself. This is shown in the example below.


In [ ]:
f2,axes = subplots(2,1)
x = range(0, stop=2π, length=1000)
@manipulate for α=1:0.1:3, β=1:0.1:3, γ=1:0.1:3, leg1="a funny plot", leg2=" an even funnier plot" 
    withfig(f2,clear=false) do
        for ax in axes
            ax[:cla]()
        end
        axes[1][:plot](x, sin.(α*x .+ cos.(β*x .+ γ)))
        axes[2][:plot](x, cos.(α*x .+ sin.(β*x .+ γ)))
        axes[1][:legend]([leg1])
        axes[2][:legend]([leg2])
    end
end

In [ ]: